<template>
   <div class="app-container">
    <h2>Demo</h2>
    <!-- 设置折叠面板 -->
    <el-collapse v-model="activeName" accordion style="margin-bottom:10px;">
      <el-collapse-item title="查询条件" name="1">
        <div>
          <!--1.查询模块 -->
          <el-form :inline="true" size="small">
            <!-- 表单元素 -->
            <el-form-item label="用户名">
              <el-input v-model="tempSearchObj.username" placeholder="用户名" />
            </el-form-item>
            <el-form-item label="审批人">
              <el-input v-model="tempSearchObj" placeholder="审批人"></el-input>
            </el-form-item>
            <el-form-item label="活动区域">
              <el-select v-model="tempSearchObj" placeholder="活动区域">
                <el-option label="区域一" value="shanghai"></el-option>
                <el-option label="区域二" value="beijing"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="活动区域">
              <el-select v-model="tempSearchObj" placeholder="活动区域">
                <el-option label="区域一" value="shanghai"></el-option>
                <el-option label="区域二" value="beijing"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="活动区域">
              <el-select v-model="tempSearchObj" placeholder="活动区域">
                <el-option label="区域一" value="shanghai"></el-option>
                <el-option label="区域二" value="beijing"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="活动区域">
              <el-select v-model="tempSearchObj" placeholder="活动区域">
                <el-option label="区域一" value="shanghai"></el-option>
                <el-option label="区域二" value="beijing"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="活动区域">
              <el-select v-model="tempSearchObj" placeholder="活动区域">
                <el-option label="区域一" value="shanghai"></el-option>
                <el-option label="区域二" value="beijing"></el-option>
              </el-select>
            </el-form-item>
            <!-- 查询与情况的按钮 -->
            <el-button type="primary" icon="el-icon-search" size="small" @click="search">查询</el-button>
            <el-button type="default" size="small" @click="resetSearch">清空</el-button>
          </el-form>
        
        </div>
      </el-collapse-item>
    </el-collapse>
  
    <!--2.添加用户 -->
    <div style="margin-bottom: 20px">
      <!-- 添加与批量添加按钮 -->
      <el-button type="primary" size="small" @click="showAddUser">添 加</el-button>
      <el-button type="danger"  :disabled="selectedIds.length===0" size="small" @click="revomveUsers"
        >批量删除</el-button>
    </div>

    <!-- 3.table表格：展示用户信息的地方 -->
    <!--  @current-change="handleCurrentChange" 管理选中时触发的事件-->
    <el-table
      size="small"
      border
      stripe
      v-loading="listLoading"
      :data="users"
      @selection-change="handleSelectionChange">

      <el-table-column
        type="selection"
        width="55" 
        align="center"
        />

      <el-table-column
        type="index"
        label="序号"
        width="80"
        align="center"
      />
      <el-table-column prop="username" label="用户名" width="150" />
      <el-table-column prop="nickName" label="用户昵称" />
      <el-table-column prop="roleName" label="权限列表" />
      
      <el-table-column prop="gmtCreate" label="创建时间" width="180"/>
      <el-table-column prop="gmtModified" label="更新时间" width="180"/>

      <el-table-column label="操作" width="230" align="center">
        <template v-slot:default="{row}">
          <HintButton type="info" size="mini" icon="el-icon-user-solid" title="分配角色"
            @click="showAssignRole(row)"/>
          <HintButton type="primary" size="mini" icon="el-icon-edit" title="修改用户"
            @click="showUpdateUser(row)"/>
          <el-popconfirm :title="`确定删除 ${row.username} 吗?`" @onConfirm="removeUser(row.id)">
            <HintButton style="margin-left:10px" slot="reference" type="danger" size="mini" icon="el-icon-delete" 
              title="删除用户"/>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <!--4.底部分页器 
            当前第几页、总共多少数据、每页展示多少数据、连续的页码数
             @size-change="handleSizeChange" 
             @current-change="handleCurrentChange"
             current-page:代表当前第几页
             total:代表分页器一共需要展示数据条数
             page-size:代表的是每页展示多少条数据
             page-sizes:表示可以设置每一页展示多少条数据
             layout：可以实现分页器的布局
             pager-count：按钮的数量9，连续的页码数7  
     -->
    <el-pagination 
        style="padding: 20px 0; text-align: center;"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-size="limit"
        :page-sizes="[5, 10, 20, 30, 40, 50, 100]"
        layout="prev, pager, next, jumper, ->, sizes, total"
        :total="total"
        :pager-count=5
          >
    </el-pagination>
   
<!-- 5.对话框-->
<!-- a.添加&修改的对话框 -->
    <el-dialog :title="user.id?'修改用户':'添加用户'" :visible.sync="dialogUserVisible"  width="40%" :before-close="cancel"> 
      <!--用户信息表单 -->
      <el-form ref="userForm" :model="user" :rules="userRules" label-width="120px">
        <el-form-item label="用户名" prop="username">
          <el-input v-model="user.username" style="width: 80%;"/>
        </el-form-item>

        <el-form-item label="用户昵称">
          <el-input v-model="user.nickName" style="width: 80%;" />
        </el-form-item>
        <!-- 用户密码自定义校验 -->
        <el-form-item v-if="!user.id" label="用户密码" prop="password">
          <el-input v-model="user.password" style="width: 80%;" />
        </el-form-item>
        <!-- <el-form-item label="确认密码" prop="checkPass">
          <el-input type="password" v-model="user.checkPass" autocomplete="off"></el-input>
        </el-form-item> -->
      </el-form>

      <div slot="footer" class="dialog-footer" >
        <el-button @click="cancel" size="small">取 消</el-button>
        <el-button :loading="loading" type="primary" @click="addOrUpdate" size="small">确 定</el-button>
      </div>
    </el-dialog>


<!-- b.分配角色对话框 -->
   <!-- 关闭前的回调，会暂停 Dialog 的关闭 function(done)，done 用于关闭 Dialog-->
    <el-dialog title="设置角色" :visible.sync="dialogRoleVisible" :before-close="resetRoleData" width="40%">
      <el-form label-width="80px">
        <el-form-item label="用户名">
          <el-input disabled :value="user.username" style="width:95%"></el-input>
        </el-form-item>
         <!-- 多选框 -->
        <el-form-item label="角色列表">          
          <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
          <div style="margin: 15px 0;"></div>
          <el-checkbox-group v-model="userRoleIds" @change="handleCheckedChange">
            <el-checkbox v-for="role in allRoles" :key="role.id" :label="role.id">{{role.roleName}}</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
    
      <div slot="footer">
        <el-button :loading="loading" type="primary" @click="SaveAssignRole" size="small">保存</el-button>
        <el-button @click="resetRoleData" size="small">取消</el-button>
      </div>
    </el-dialog>
   </div>
</template>
 
<script>
 
 export default {
    name: 'Dome',
    data() {
     return {
       activeName: '1',


       currentPage: 1, // 当前页码
       limit: 5, // 每页数量
       total: 0, // 总数量
       listLoading: false, // 是否显示列表加载的提示
       searchObj: { // 包含请求搜索条件数据的对象
         username: ''
       },
       tempSearchObj: { // 收集搜索条件输入的对象
         username: ''
       },
       users: [], // 当前页的用户列表
       selectedIds: [], // 存储所有选择的user的id的数组
  
       user: {}, // 当前要操作的user
 
       //添加or修改用户信息对话框控制,是否显示角色Dialog
       dialogUserVisible: false,
       //分配角色信息对话框控制
       dialogRoleVisible: false,   
 
       userRules: { // 用户添加/修改表单的校验规则
         username: [
           { required: true, message: '用户名必须输入' },
           { min: 4, message: '用户名不能小于4位' }
         ],
         password: [
           { required: true, validator:this.validatePassWord }
         ]
       },
       loading: false, // 是否正在提交请求中
 
       /* 多选框数据 */
       allRoles: [], // 存储所有角色的列表
       userRoleIds: [], // 用户的角色ID的列表
       /* 全选框的多个状态 */
       isIndeterminate: false, //有选中，未全选也没有全不选
       checkAll: false, // 是否全选
     }
    },
    methods:{
      /*current-change事件来管理选中时触发的事件，它会传入currentRow，oldCurrentRow*/ 
       handleSelectionChange(selection){
              this.selectedIds = selection.map((item)=>{
                     return item.id
              })
       },
 
     /* 批量删除用户信息*/
       revomveUsers(){
         //MessageBox弹框
         this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
           confirmButtonText: '确定',
           cancelButtonText: '取消',
           type: 'warning'
         }).then(async () => {
         await this.$API.user.removeUsers(this.selectedIds)
         this.$message.success('删除成功')
         this.getUsers()
       }).catch(() => {
         this.$message.info('取消删除')
       })
       },
       
     /* 分页器 */
       handleSizeChange(val){
         // console.log(`每页 ${val} 条`);
         // 修改当前页展示数据条数
           this.limit = val
           this.getUsers()
       },
       handleCurrentChange(val){
         // console.log(`当前页: ${val}`);
           this.getUsers(val)
       },
 
     /* 
     获取用户信息分页列表
     */
         async getUsers (page=1) {
           this.currentPage = page
           //请求搜索条件的对象searchObj,携带query参数，后台进行模糊查询返回数据
           const {limit, searchObj} = this
           //请求后开启加载效果
           this.listLoading = true
           const result = await this.$API.user.getPageList(page, limit, searchObj)
           //响应成功，关闭加载
           this.listLoading = false
           const {items, total} = result.data
           //过滤掉username中的admin,将不等于admin的用户生成新的数组返回
           this.users = items.filter(item => item.username!=='admin')
           // this.users = items
           //问题：返回的总条数total多了1
           this.total = total -1
           this.selectedIds = []
         },
       
       /*用户查询功能*/
       search(){
           this.searchObj = {...this.tempSearchObj}
           this.getUsers()
       },
       /* 清除搜索栏 */
       resetSearch(){
           this.searchObj = {
             username: ''
           }
           this.tempSearchObj = {
             username: ''
           }
           this.getUsers()
       },
 
       /* 添加用户的事件*/
       showAddUser(){
           //清空修改查看时的数据
           this.user = {}
           this.dialogUserVisible = true
           // 清除校验(必须在界面更新之后)
           this.$nextTick(() => this.$refs.userForm.clearValidate())
       },
       //用户对话框取消
       cancel(){
         this.dialogUserVisible = false
         // 问题：取消时清空，对话框隐藏过程中，密码框会显示出来
         // this.user = {}
         setTimeout(()=>{
           this.user = {}
         },200)
       },
 
       //添加&修改用户信息的确认事件
       addOrUpdate(){
         //表单校验通过
           this.$refs.userForm.validate(valid => {
           if (valid) {
             const {user} = this
             this.loading = true
             // 语法：对象["属性名"] = 属性值
              this.$API.user[user.id ? 'update' : 'add'](user).then((result) => {
               this.loading = false
               // 弹出信息：添加品牌成功、修改品牌成功
               this.$message({
                 //修改时拿到的是服务器返回的数据有id值
                        message:(user.id ?'修改用户成功':"添加用户成功"),
                        type:'success'
                     })
               // 如果添加用户：停留在第一页，修改用户应该停留在当前页面
               this.getUsers(user.id ? this.currentPage : 1)
               //退出清空数据,在点击添加按钮是也有清空操作
               this.user = {}
               this.dialogUserVisible = false
             })
           }
         })
       },
 
       /* 自定义密码校验*/
        validatePassWord(rule, value, callback){
         /*  使用test()方法检查字符串是否符合正则表达式的规则，
         如果符合则返回true，否则返回false */
         let  pwdFlog = /^[a-zA-Z0-9_-]{6,16}$/.test(value)
         if(!value){
           callback(new Error('密码不能为空'))
         }else if(!pwdFlog) {
             value.length < 6 ? callback('密码不能小于6位'):callback('密码格式不正确')
         }else{
           callback()
         }
       },
  /*   validatePassWord2(rule, value, callback){
         if (value === '') {
           callback(new Error('请再次输入密码'));
         } else if (value !== this.user.password) {
           callback(new Error('两次输入密码不一致!'));
         } else {
           callback();
         }
       }, */
 
       /* 操作模块的事件回调 */
       //分配用户角色
       async showAssignRole(curruser){
           this.user = {...curruser}
           this.dialogRoleVisible = true
           const result = await this.$API.user.getRoles(curruser.id)
           if (result.code == 20000 || result.code == 200) {
             const { allRolesList, assignRoles } = result.data
             this.allRoles = allRolesList
             this.userRoleIds = assignRoles.map(item => item.id)
 
             //要判断单选是否全部勾选，而改变全选框的状态
              const {allRoles,userRoleIds} = this
              this.checkAll = userRoleIds.length === allRoles.length && allRoles.length > 0
              this.isIndeterminate = userRoleIds.length > 0 && userRoleIds.length < allRoles.length
             }
       },
       // 修改用户回调
       showUpdateUser(curruser){
         //这里需要用到深拷贝,数据结构只有一层,浅拷贝也行
         // this.user = cloneDeep(curruser)   
         this.user = {...curruser}
         this.dialogUserVisible = true
           
       },
       //删除用户信息的回调
       async removeUser(userid){
             await this.$API.user.removeById(userid)
             this.$message({
               message: '删除成功',
               type: 'success'
             })
             //再次获取用户信息数据,this.users.length>1说明当前页的数据大于1,如果小于1删除后展示前面一页
             this.getUsers(this.users.length>1?this.currentPage:this.currentPage -1);
       },
      
       /*分配角色多选框的回调*/
       //全选
       handleCheckAllChange(val){// val 当前勾选状态true/false
       // 如果当前全选, userRoleIds就是所有角色id的数组, 否则是空数组
       this.userRoleIds = val ? this.allRoles.map(item => item.id) : []
       // 如果当前不是全选也不全不选时, 指定为false
       this.isIndeterminate = false
       },
       //单个多选
       handleCheckedChange(value){
         //value为选中的所有角色id的数组
         const {allRoles,userRoleIds} = this
         //要判断单选是否全部勾选，而改变全选框的状态
         this.checkAll = userRoleIds.length === allRoles.length && allRoles.length > 0 
         this.isIndeterminate = userRoleIds.length > 0 && userRoleIds.length < allRoles.length
       },
       //保存角色分配
       async SaveAssignRole(){
           const {user,userRoleIds} = this
           const userId = user.id
           //数组行不通，join() 方法将数组作为字符串返回。
           const roleId = userRoleIds.join()
           this.loading = true
           const result = await this.$API.user.assignRoles(userId,roleId)
           if(result.code == 20000 || result.code == 200){
               this.loading = false
               this.$message.success('角色分配成功')
               //重置用户角色数据
               this.resetRoleData()
               //刷新用户管理列表
               this.getUsers(this.currentPage)
               //如果配置的用户是当前用户，则重新加载当前页面
               console.log(this.$store.getters.name, this.user)
               if (this.$store.getters.name===this.user.username) {
                    window.location.reload()
                }
           }
        
       },
       //取消分配角色对话框-- 重置用户角色的数据
       resetRoleData(){
          this.dialogRoleVisible = false 
         //清除勾选的数据
          this.userRoleIds = []
          this.allRoles = []
         //全选框复位
          this.checkAll = false
          this.isIndeterminate = false
       }
    },
    //发请求一般情况下，我们都是在mounted去发，但是也可以在created内部去
    mounted() {
         this.getUsers()
   },
 
 }
 </script>
 
<style>
   .app-container{
      margin:10px 0px;
   }
 </style>